﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net.Security;
using System.IO;
using System.Diagnostics;
using JMailT.Data;

namespace JMailT.GMail
{
    public class GMailPop3
    {
        public string Host { get; set; }
        public int Port { get; set; }

        private TcpClient _tcpClient;
        private SslStream _stream;
        private StreamReader _reader;
        private Encoding _encoding = Encoding.UTF8;

        public GMailPop3(string host, int port)
        {
            Host = host;
            Port = port;
        }

        public Pop3Result Connect()
        {
            try
            {
                _tcpClient = new TcpClient(Host, Port);
                _stream = new SslStream(_tcpClient.GetStream(), false);
                _stream.AuthenticateAsClient(Host);
                _reader = new StreamReader(_stream, _encoding);
                string message = _reader.ReadLine();
                Debug.WriteLine(message);

                return new Pop3Result(message);
            }
            catch (System.Exception ex)
            {
                //exception_pro = ex;
                //isConnected_pro = false;
                Debug.WriteLine(ex.Message);
                return new Pop3Result(ex);
            }
        }

        public void Disconnect()
        {
            WriteToNetStream(ref _stream, "QUIT");
            if (_reader != null)
            {
                _reader.Close();
            }
            if (_stream != null)
            {
                _stream.Close();
            }
            if (_tcpClient != null)
            {
                _tcpClient.Close();
            }
        }

        public bool Login(string uid, string pwd)
        {
            WriteToNetStream(ref _stream, "USER " + uid);
            string message = _reader.ReadLine();
            Debug.WriteLine(message);

            WriteToNetStream(ref _stream, "PASS " + pwd);
            message = _reader.ReadLine();
            Debug.WriteLine(message);

            return true;
        }

        private void WriteToNetStream(ref SslStream netStream, string command)
        {
            string strToSend = command + "\r\n";
            byte[] arrayToSend = System.Text.Encoding.UTF8.GetBytes(strToSend.ToCharArray());
            netStream.Write(arrayToSend, 0, arrayToSend.Length);
        }

        public Pop3Result Stat()
        {
            WriteToNetStream(ref _stream, "STAT");

            string strMessage = _reader.ReadLine();
            Debug.WriteLine(strMessage);
            return new Pop3Result(strMessage);
        }

        public Pop3Result List()
        {
            WriteToNetStream(ref _stream, "LIST");

            string strMessage = _reader.ReadLine();
            string strTemp = null;
            while (strMessage != ".")
            {
                strTemp = strTemp + strMessage;
                strMessage = _reader.ReadLine();
            }
            Debug.WriteLine(strTemp);
            return new Pop3Result(strTemp);
        }

        public Pop3Result Top(int id, int row)
        {
            WriteToNetStream(ref _stream, string.Format("TOP {0} {1}", id, row));

            string strMessage = _reader.ReadLine();
            string strTemp = null;
            while (strMessage != ".")
            {
                strTemp = strTemp + strMessage;
                strMessage = _reader.ReadLine();
            }
            Debug.WriteLine(strTemp);
            return new Pop3Result(strTemp);
        }

        public Pop3Result Uidl(int index)
        {
            WriteToNetStream(ref _stream, string.Format("UIDL {0}", index));

            string strMessage = _reader.ReadLine();
            Debug.WriteLine(strMessage);
            return new Pop3Result(strMessage);
        }

        public Pop3Result Retr(int index)
        {
            WriteToNetStream(ref _stream, string.Format("RETR {0}", index));

            string strMessage = _reader.ReadLine();
            string strTemp = null;
            while (strMessage != ".")
            {
                strTemp = strTemp + strMessage;
                strTemp += Environment.NewLine;
                strMessage = _reader.ReadLine();
            }
            Debug.WriteLine(strTemp);
            return new Pop3Result(strTemp);
        }

        public Pop3Result Noop()
        {
            MailList list = new MailList();
            WriteToNetStream(ref _stream, "NOOP");
            string strMessage = _reader.ReadLine();
            Debug.WriteLine(strMessage);
            return new Pop3Result(strMessage);
        }

        public MailList List2()
        {
            MailList list = new MailList();
            WriteToNetStream(ref _stream, "LIST");
            string strMessage = _reader.ReadLine();
            if (strMessage == "+OK")
            {
                strMessage = _reader.ReadLine();
                list.Count = Convert.ToInt32(strMessage);
            }
            return list;
        }
    }
}
